package com.xthh._function;

import android.app.ActivityManager;
import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.os.StatFs;
import android.provider.DocumentsContract;
import android.provider.MediaStore;


import com.xthh._struct.HH_T_DIR_INFO;
import com.xthh._struct.HH_T_FILEFOLDER;
import com.xthh._struct.HH_T_MsgTask;
import com.xthh._struct.HH_T_SYSTEMTIME;

import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.nio.charset.Charset;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

public class HH_FileUtil {
    private static final String TAG = "XTHH_FileUtil";
    private static DecimalFormat fileIntegerFormat = new DecimalFormat("#0");
    private static DecimalFormat fileDecimalFormat = new DecimalFormat("#0.#");

   //  测试用的，获取磁盘文件夹 参数的扩展名，是带.的
    public static String GetTestPath(String ext){
        String sTime = HH_TimeUtil.GetCurrentSystemTimeF();
        return String.format("%s%s%s%s", Environment.getExternalStorageDirectory().toString(), "/", sTime, ext);
    }

    // 删除文件或文件夹
    public static boolean Delete(String fileName) {
        File file = new File(fileName);
        if (!file.exists()) {
            return false;
        } else {
            if (file.isFile())
                return DeleteFile(fileName);
            else
                return DeleteDirectory(fileName);
        }
    }

    // 删除文件
    public static boolean DeleteFile(String fileName) {
        if (fileName == null)
            return false;

        File file = new File(fileName);
        // 如果文件路径所对应的文件存在，并且是一个文件，则直接删除
        if (file.exists() && file.isFile()) {
            if (file.delete()) {
                return true;
            } else {
                return false;
            }
        } else {
            return false;
        }
    }

    public static void DeleteTempBmpFiles(Context ctx){
        String rootDataDir = HH_FileUtil.GetStoragePath(ctx);

        if (!rootDataDir.endsWith(File.separator))
            rootDataDir = rootDataDir + File.separator;
        File dirFile = new File(rootDataDir);

        File[] files = dirFile.listFiles();
        for (int i = 0; i < files.length; i++) {
            // 删除子文件
            if (files[i].isFile()) {
                ///data/user/0/com.clj.blesample/files/20221128151011.bmp
                HH_T_DIR_INFO tdi = HH_FileUtil.GetCurFileInfo(files[i].toString());
                int len = tdi.getName().length();
                if (tdi.getName() != null && tdi.getName().length() == 14 && HH_CharUtil.IsCheckStr(tdi.getName(), "0123456789") && HH_CharUtil.Strcmp(tdi.getExtN(), "bmp", true)){
                    len++;
                    System.out.println("删除目录失败:" + "不存在！" + files[i].toString());

                    Delete(files[i].toString());
                }
            }
        }
    }

    // 删除目录及目录下面的文件
    public static boolean DeleteDirectory(String dir) {
        // 如果dir不以文件分隔符结尾，自动添加文件分隔符
        if (!dir.endsWith(File.separator))
            dir = dir + File.separator;
        File dirFile = new File(dir);
        // 如果dir对应的文件不存在，或者不是一个目录，则退出
        if ((!dirFile.exists()) || (!dirFile.isDirectory())) {
            System.out.println("删除目录失败:" + dir + "不存在！");
            return false;
        }
        boolean flag = true;
        // 删除文件夹中的所有文件包括子目录
        File[] files = dirFile.listFiles();
        for (int i = 0; i < files.length; i++) {
            // 删除子文件
            if (files[i].isFile()) {
                flag = HH_FileUtil.DeleteFile(files[i].getAbsolutePath());
                if (!flag)
                    break;
            }
            // 删除子目录
            else if (files[i].isDirectory()) {
                flag = HH_FileUtil.DeleteDirectory(files[i].getAbsolutePath());
                if (!flag)
                    break;
            }
        }
        if (!flag) {
            return false;
        }
        // 删除当前目录
        if (dirFile.delete()) {
            return true;
        } else {
            return false;
        }
    }

    // 检测SD卡是否存在
    public static boolean ExternalMemoryAvailable() {
        return Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED);
    }

    // 获取手机内部剩余存储空间
    public static long GetAvailableInternalMemorySize() {
        File path = Environment.getDataDirectory();
        StatFs stat = new StatFs(path.getPath());
        long blockSize = stat.getBlockSize();
        long availableBlocks = stat.getAvailableBlocks();
        return availableBlocks * blockSize;
    }

    // 获取手机内部总的存储空间
    public static long GetTotalInternalMemorySize() {
        File path = Environment.getDataDirectory();
        StatFs stat = new StatFs(path.getPath());
        long blockSize = stat.getBlockSize();
        long totalBlocks = stat.getBlockCount();
        return totalBlocks * blockSize;
    }

    // 获取SDCARD剩余存储空间
    public static long GetAvailableExternalMemorySize() {
        if (ExternalMemoryAvailable()) {
            File path = Environment.getExternalStorageDirectory();
            StatFs stat = new StatFs(path.getPath());
            long blockSize = stat.getBlockSize();
            long availableBlocks = stat.getAvailableBlocks();
            return availableBlocks * blockSize;
        } else {
            return -1;
        }
    }

    // 获取SDCARD总的存储空间
    public static long GetTotalExternalMemorySize() {
        if (ExternalMemoryAvailable()) {
            File path = Environment.getExternalStorageDirectory();
            StatFs stat = new StatFs(path.getPath());
            long blockSize = stat.getBlockSize();
            long totalBlocks = stat.getBlockCount();
            return totalBlocks * blockSize;
        } else {
            return -1;
        }
    }

    // 获取系统总内存
    public static long GetTotalMemorySize(Context context) {
        String dir = "/proc/meminfo";
        try {
            FileReader fr = new FileReader(dir);
            BufferedReader br = new BufferedReader(fr, 2048);
            String memoryLine = br.readLine();
            String subMemoryLine = memoryLine.substring(memoryLine.indexOf("MemTotal:"));
            br.close();
            return Integer.parseInt(subMemoryLine.replaceAll("\\D+", "")) * 1024l;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return 0;
    }

    // 获取当前可用内存，返回数据以字节为单位
    public static long GetAvailableMemory(Context context) {
        ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
        ActivityManager.MemoryInfo memoryInfo = new ActivityManager.MemoryInfo();
        am.getMemoryInfo(memoryInfo);
        return memoryInfo.availMem;
    }

    // 单位换算
    public static String FormatFileSize(long size, boolean isInteger) {
        DecimalFormat df = isInteger ? fileIntegerFormat : fileDecimalFormat;
        String fileSizeString = "0M";
        if (size < 1024 && size > 0) {
            fileSizeString = df.format((double) size) + "B";
        } else if (size < 1024 * 1024) {
            fileSizeString = df.format((double) size / 1024) + "K";
        } else if (size < 1024 * 1024 * 1024) {
            fileSizeString = df.format((double) size / (1024 * 1024)) + "M";
        } else {
            fileSizeString = df.format((double) size / (1024 * 1024 * 1024)) + "G";
        }
        return fileSizeString;
    }

    // 刷新的磁盘根目录
    // 磁盘写入完文件后需要刷新，否则看不到文件
    // 由于现在很多手机因为容量足够,不再外插SD卡,获取的外部存储路径就是在手机根目录下,而手机对于外部存储的文件有一个扫描机制,直接写入文件到手机外部存储由于系统未重新扫描外部存储,所以在电脑上显示不了文件,而重命名文件和重启手机的方式可以触发扫描机制,所以这两个操作之后就可以在电脑上看到该文件
    public static void ScannerFile(Context mContext) {
        Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
        File file = new File(GetStoragePath(mContext));
        Uri uri = Uri.fromFile(file);
        intent.setData(uri);
        mContext.sendBroadcast(intent);
    }

    // 刷新指定路径的
    public static void ScannerFile(Context mContext, String path) {
        Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
        File file = new File(path);
        Uri uri = Uri.fromFile(file);
        intent.setData(uri);
        mContext.sendBroadcast(intent);
    }

    public static void CreateFolder(String str) {
        if (str == null || str.length() <= 0)
            return;
        File destDir = new File(str);
        if (!destDir.exists()) {
            destDir.mkdirs();
        }
    }

    // 判断文件是否存在
    public static boolean IsExists(String strFile) {
        if (strFile == null || strFile.length() <= 0)
            return  false;

        try {
            File f = new File(strFile);
            if (!f.exists()) {
                return false;
            }
        } catch (Exception e) {
            return false;
        }

        return true;
    }

    // 获取存储磁盘路径
    public static String GetStoragePath(Context mContext) {
        //return Environment.getExternalStorageDirectory().getPath();//外部存储一般是指SDCard，外部存储中的文件是可以被用户或者其他应用程序修改的
        return mContext.getApplicationContext().getFilesDir().getAbsolutePath();// 私有内部存储是App的私有目录，当一个应用卸载之后，内部存储中的这些文件也被删除。Shared Preferences和SQLite数据库文件都是存储在内部存储空间上的。
    }

    public static List<File> SearchFolder(File file) {
        List<File> folders = new ArrayList<File>();

        if (file.isDirectory()) {
            File[] files = file.listFiles();
            if (files != null) {
                for (File childFile : files) {
                    if (childFile.isDirectory()) {
                        folders.add(childFile);
                    }
                }
            }
        }
        return folders;
    }

    public static List<String> SearchFolder(String path) {
        if (path == null)
            return null;

        File srcFile = new File(path);
        List<String> folders = new ArrayList<String>();

        if (srcFile.isDirectory()) {
            File[] files = srcFile.listFiles();
            if (files != null) {
                for (File childFile : files) {
                    if (childFile.isDirectory()) {
                        folders.add(childFile.toString());
                    }
                }
            }
        }
        return folders;
    }

    // 搜索目录下的所有文件 后面的参数没用 当前都是获取的文件
    public static List<String> SearchFiles(String path, boolean isFile) {
        List<String> lResult = new ArrayList<String>();

        if (IsExists(path)) {
            File srcFile = new File(path);
            if (srcFile != null && srcFile.isDirectory()) {
                File[] files = srcFile.listFiles();
                if (files != null) {
                    for (File childFile : files) {
                        if (isFile){
                            if (!childFile.isDirectory()) {
                                lResult.add(childFile.toString());
                            }
                        } else {
                            if (childFile.isDirectory()) {
                                lResult.add(childFile.toString());
                            }
                        }
                    }
                }
            }
        }

        return lResult;
    }




    public static List<File> SearchFiles(File file) {
        List<File> lResult = new ArrayList<File>();

        if (file.isDirectory()) {
            File[] files = file.listFiles();
            if (files != null) {
                for (File childFile : files) {
                    if (!childFile.isDirectory()) {
                        lResult.add(childFile);
                    }
                }
            }
        }

        return lResult;
    }

    public static boolean CopyFile(String oldPath, String newPath) {
        try {
            File oldFile = new File(oldPath);

            if (!oldFile.exists() || !oldFile.isFile() || !oldFile.canRead()) {
                return false;
            }

            FileInputStream fileInputStream = new FileInputStream(oldPath);
            FileOutputStream fileOutputStream = new FileOutputStream(newPath);
            byte[] buffer = new byte[1024];
            int byteRead;
            while (-1 != (byteRead = fileInputStream.read(buffer))) {
                fileOutputStream.write(buffer, 0, byteRead);
            }
            fileInputStream.close();
            fileOutputStream.flush();
            fileOutputStream.close();
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    // 写文件，最后一个参数表示追加
    public static void WriteFile(Context context, String path, String content, boolean append) {
        if (content == null)
            return;

        FileOutputStream outputStream = null;
        try {
            outputStream = new FileOutputStream(path, append);
            outputStream.write(content.getBytes());
            outputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    // 写文件，最后一个参数表示追加
    public static void WriteFile(String path, String content, boolean append) {
        if (content == null)
            return;

        FileOutputStream outputStream = null;
        try {
            outputStream = new FileOutputStream(path, append);
            outputStream.write(content.getBytes());
            outputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    // 写文件，最后一个参数表示追加
    public static void WriteFile(Context context, String path, List<Integer> list81, boolean append) {
        if (list81 == null)
            return;;

        byte []arrayWrite = new byte[list81.size()];
        for (int i = 0; i < list81.size(); i++)
            arrayWrite[i] = list81.get(i).byteValue();

        FileOutputStream outputStream = null;
        try {
            outputStream = new FileOutputStream(path, append);
            outputStream.write(arrayWrite);
            outputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    // 写文件，最后一个参数表示追加
    public static void WriteFileHex(Context context, String path, List<Integer> list81, boolean append) {
        if (list81 == null)
            return;;

        String strHex = "";
        for (int i = 0; i < list81.size(); i++){
            strHex += String.format("%02x ", list81.get(i).byteValue());
        }

        FileOutputStream outputStream = null;
        try {
            outputStream = new FileOutputStream(path, append);
            outputStream.write(strHex.getBytes());
            outputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    public static void WriteFile(String path, byte []content, boolean append) {
        FileOutputStream outputStream = null;
        try {
            outputStream = new FileOutputStream(path, append);
            outputStream.write(content);
            outputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }




    public static String ReadFile(Context context, String path) {
        StringBuilder sb = new StringBuilder("");

        FileInputStream inputStream;
        try {
            inputStream = new FileInputStream(path);
            byte[] buffer = new byte[1024];
            int len = inputStream.read(buffer);
            while (len > 0) {
                sb.append(new String(buffer, 0, len));
                len = inputStream.read(buffer);
            }
            inputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

        return sb.toString();
    }

    public static byte [] ReadFileB(Context context, String path) {
        if (path == null)
            return null;
        //StringBuilder sb = new StringBuilder("");

        ByteArrayOutputStream os = new ByteArrayOutputStream();

        FileInputStream inputStream;
        try {
            inputStream = new FileInputStream(path);
            byte[] buffer = new byte[1024];
            int len = inputStream.read(buffer);
            while (len > 0) {
                //sb.append(new String(buffer, 0, len));
                os.write(buffer, 0, len);
                len = inputStream.read(buffer);
            }
            inputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

        return os.toByteArray();
    }

    // 获取目录下面的所有文件和文件夹
    public static HH_T_FILEFOLDER GetAllFilesAndFolders(String path) {
        HH_T_FILEFOLDER ff = new HH_T_FILEFOLDER();

        List<String> listFolders = new ArrayList<String>();
        List<String> listFiles = new ArrayList<String>();

        int fileNum = 0, folderNum = 0;
        File file = new File(path);
        if (file.exists()) {
            LinkedList<File> list = new LinkedList<File>();
            File[] files = file.listFiles();
            if (files != null){
                for (File file2 : files) {
                    if (file2.isDirectory()) {
                        listFolders.add(file2.getAbsolutePath());
                        list.add(file2);
                        folderNum++;
                    } else {
                        listFiles.add(file2.getAbsolutePath());
                        fileNum++;
                    }
                }
                File temp_file;
                while (!list.isEmpty()) {
                    temp_file = list.removeFirst();
                    files = temp_file.listFiles();
                    for (File file2 : files) {
                        if (file2.isDirectory()) {
                            listFolders.add(file2.getAbsolutePath());
                            list.add(file2);
                            folderNum++;
                        } else {
                            listFiles.add(file2.getAbsolutePath());
                            fileNum++;
                        }
                    }
                }
            }

        }

        ff.setFiles(listFiles);
        ff.setFolders(listFolders);
        return ff;
    }

    // 获取目录下面的所有文件和文件夹
    public static HH_T_FILEFOLDER GetAllFolders(String path) {
        HH_T_FILEFOLDER ff = new HH_T_FILEFOLDER();

        List<String> listFolders = new ArrayList<String>();

        File file = new File(path);
        if (file.exists()) {
            LinkedList<File> list = new LinkedList<File>();
            File[] files = file.listFiles();
            for (File file2 : files) {
                if (file2.isDirectory()) {
                    listFolders.add(file2.getAbsolutePath());
                    list.add(file2);
                } else {
                }
            }
        }

        ff.setFolders(listFolders);
        return ff;
    }

    // 按行读文件
    public static List<String> ReadFileByLines(String fileName) {
        List<String> listSrc = new ArrayList<String>();

        File file = new File(fileName);
        BufferedReader reader = null;
        try {
            // System.out.println("以行为单位读取文件内容，一次读一整行：");
            reader = new BufferedReader(new FileReader(file));
            String tempString = null;
            int line = 1;
            // 一次读入一行，直到读入null为文件结束
            while ((tempString = reader.readLine()) != null) {
                listSrc.add(tempString);
                line++;
            }
            reader.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

        return listSrc;
    }

    // 根据路径，获取文件名
    public static HH_T_DIR_INFO GetCurFileInfo(String path) {
        // /storage/emulated/0/tencent/MicroMsg/sns_ad_landingpages/adId_img_25a2ed99b70a3a39bf753beb06ead349
        // /storage/emulated/0/tencent/MicroMsg/sns_ad_landingpages/adId_img_25a2ed99b70a3a39bf753beb06ead349.123
        HH_T_DIR_INFO di = new HH_T_DIR_INFO();

        if (path == null || path.length() <= 0)
            return di;

        int start = path.lastIndexOf("/");
        if (start != -1) {
            String p = path.substring(0, start + 1);
            di.setPath(p);

            String nameF = path.substring(start + 1);
            di.setNameF(nameF);

            start = nameF.lastIndexOf(".");
            // 123.456
            // 0123
            if (start != -1) {
                String name = nameF.substring(0, start);


                String ext = nameF.substring(start + 1);

                di.setExt("." + ext);
                di.setExtN(ext);
                di.setName(name);
            } else {
                // 这里是没有扩展名的文件
                di.setName(nameF);
                di.setExt("");
                di.setExtN("");
            }
        }

        return di;
    }




    public static String getFilePathByUri(Context context, Uri uri) {
        String path = null;
        // 以 file:// 开头的
        if (ContentResolver.SCHEME_FILE.equals(uri.getScheme())) {
            path = uri.getPath();
            return path;
        }
        // 以 content:// 开头的，比如 content://media/extenral/images/media/17766
        if (ContentResolver.SCHEME_CONTENT.equals(uri.getScheme()) && Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
            Cursor cursor = context.getContentResolver().query(uri, new String[]{MediaStore.Images.Media.DATA}, null, null, null);
            if (cursor != null) {
                if (cursor.moveToFirst()) {
                    int columnIndex = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
                    if (columnIndex > -1) {
                        path = cursor.getString(columnIndex);
                    }
                }
                cursor.close();
            }
            return path;
        }
        // 4.4及之后的 是以 content:// 开头的，比如 content://com.android.providers.media.documents/document/image%3A235700
        if (ContentResolver.SCHEME_CONTENT.equals(uri.getScheme()) && Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            if (DocumentsContract.isDocumentUri(context, uri)) {
                if (isExternalStorageDocument(uri)) {
                    // ExternalStorageProvider
                    final String docId = DocumentsContract.getDocumentId(uri);
                    final String[] split = docId.split(":");
                    final String type = split[0];
                    if ("primary".equalsIgnoreCase(type)) {
                        path = Environment.getExternalStorageDirectory() + "/" + split[1];
                        return path;
                    }
                } else if (isDownloadsDocument(uri)) {
                    // DownloadsProvider
                    final String id = DocumentsContract.getDocumentId(uri);
                    final Uri contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"),
                            Long.valueOf(id));
                    path = getDataColumn(context, contentUri, null, null);
                    return path;
                } else if (isMediaDocument(uri)) {
                    // MediaProvider
                    final String docId = DocumentsContract.getDocumentId(uri);
                    final String[] split = docId.split(":");
                    final String type = split[0];
                    Uri contentUri = null;
                    if ("image".equals(type)) {
                        contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
                    } else if ("video".equals(type)) {
                        contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
                    } else if ("audio".equals(type)) {
                        contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
                    }
                    final String selection = "_id=?";
                    final String[] selectionArgs = new String[]{split[1]};
                    path = getDataColumn(context, contentUri, selection, selectionArgs);
                    return path;
                }
            }
        }
        return null;
    }

    private static String getDataColumn(Context context, Uri uri, String selection, String[] selectionArgs) {
        Cursor cursor = null;
        final String column = "_data";
        final String[] projection = {column};
        try {
            cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs, null);
            if (cursor != null && cursor.moveToFirst()) {
                final int column_index = cursor.getColumnIndexOrThrow(column);
                return cursor.getString(column_index);
            }
        } finally {
            if (cursor != null)
                cursor.close();
        }
        return null;
    }

    private static boolean isExternalStorageDocument(Uri uri) {
        return "com.android.externalstorage.documents".equals(uri.getAuthority());
    }

    private static boolean isDownloadsDocument(Uri uri) {
        return "com.android.providers.downloads.documents".equals(uri.getAuthority());
    }

    private static boolean isMediaDocument(Uri uri) {
        return "com.android.providers.media.documents".equals(uri.getAuthority());
    }



    public static byte[] GetMsgBinInfo(HH_T_MsgTask tms) {

        String title = tms.getMsgTaskTitle();
        String content = tms.getMsgTaskContnet();

        if (title == null || title.length() <= 0 || content == null || content.length() <= 0)
            return null;

        byte[] pTitleAnsi = title.getBytes(Charset.forName("US-ASCII"));
        byte[] pContentAnsi = content.getBytes(Charset.forName("US-ASCII"));
        byte[] pTitleUnicode_UCS2 = title.getBytes(Charset.forName("UTF-16BE"));
        byte[] pContentUnicode_UCS2 = content.getBytes(Charset.forName("UTF-16BE"));
        byte[] pTitleUnicode_UCS4 = title.getBytes(Charset.forName("UTF-32BE"));
        byte[] pContentUnicode_UCS4= content.getBytes(Charset.forName("UTF-32BE"));

        byte[] pTitleGBK = HH_CharUtil.ToGBK(title);
        byte[] pContentGBK =  HH_CharUtil.ToGBK(content);


        // 消息ID
        byte[] szMSGID = HH_SystemUtil.Variable32ToArray(tms.getMsgTaskID());

        // 时间
        HH_T_SYSTEMTIME st = HH_TimeUtil.GetLocalTime();
        int nYear = HH_CharUtil.XTHH_DectoBCD(String.format("%d", st.getYear() - 2000));
        int nMonth = HH_CharUtil.XTHH_DectoBCD(String.format("%d", st.getMonth()));
        int nDay = HH_CharUtil.XTHH_DectoBCD(String.format("%d", st.getDay()));
        int nHour = HH_CharUtil.XTHH_DectoBCD(String.format("%d", st.getHour()));
        int nMinute = HH_CharUtil.XTHH_DectoBCD(String.format("%d", st.getMinute()));
        int nSecond = HH_CharUtil.XTHH_DectoBCD(String.format("%d", st.getSecond()));


        // 估计一个长度，方便保存数据
        int nMaxLen = 4096;

        // 以下是整合数据
        byte []pSaveInfo = new byte[nMaxLen];
        int index = 0;

        // 头识别信息
        if (index + 4 < nMaxLen)
        {
            pSaveInfo[index++] = 'X';
            pSaveInfo[index++] = 'M';
            pSaveInfo[index++] = 'S';
            pSaveInfo[index++] = 'G';
        }

        if (index + 4 < nMaxLen)
        {
            // 内容累加和
            //&pSaveInfo[index];
            index += 4;
        }

        if (index + 4 < nMaxLen)
        {
            // 文件长度
            //&pSaveInfo[index];
            index += 4;
        }

        if (index + 1 < nMaxLen)
        {
            // 文件标识
            pSaveInfo[index++] = 0x01;// 表示消息文件
        }

        // 压缩标识
        if (index + 1 < nMaxLen)
            pSaveInfo[index++] = 0x00;// 暂未使用

        // 以下是消息内容格式
        if (index + 4 < nMaxLen)
        {
            pSaveInfo[index++] = szMSGID[0];
            pSaveInfo[index++] = szMSGID[1];
            pSaveInfo[index++] = szMSGID[2];
            pSaveInfo[index++] = szMSGID[3];
        }

        // 消息类型 权重
        if (index + 1 < nMaxLen)
        {
            pSaveInfo[index++] = (byte)tms.getMsgTaskMsgType();
        }

        // 消息时间 年月日时分 5字节的BCD
        if (index + 6 < nMaxLen)
        {
            pSaveInfo[index++] = (byte)nYear;
            pSaveInfo[index++] = (byte)nMonth;
            pSaveInfo[index++] = (byte)nDay;
            pSaveInfo[index++] = (byte)nHour;
            pSaveInfo[index++] = (byte)nMinute;
            pSaveInfo[index++] = (byte)nSecond;
        }

        // 字库类型
        if (index + 1 < nMaxLen)
        {
            if (tms.getMsgTaskFontType() == 3)
            {
                pSaveInfo[index++] = 2;
            }
            else if (tms.getMsgTaskFontType() == 2)
            {
                pSaveInfo[index++] = 0;
            }
            else
            {
                pSaveInfo[index++] = 1;
            }
        }

        // 标题长
        if (index + 1 < nMaxLen)
        {
            switch (tms.getMsgTaskFontType())
            {
                case 0:
                    pSaveInfo[index++] = (byte)pTitleUnicode_UCS4.length;
                    break;
                case 1:
                    pSaveInfo[index++] = (byte)pTitleAnsi.length;
                    break;
                case 2:
                    pSaveInfo[index++] = (byte)pTitleUnicode_UCS2.length;
                    break;
                case 3:
                    pSaveInfo[index++] = (byte)pTitleGBK.length;
                    break;
            }
        }

        // 内容长
        if (index + 1 < nMaxLen)
        {
            byte []bContentLen = new byte[2];
            switch (tms.getMsgTaskFontType())
            {
                case 0:
                    bContentLen = HH_SystemUtil.Variable16ToArray(pContentUnicode_UCS4.length);
                    break;
                case 1:
                    bContentLen = HH_SystemUtil.Variable16ToArray(pContentAnsi.length);
                    break;
                case 2:
                    bContentLen = HH_SystemUtil.Variable16ToArray(pContentUnicode_UCS2.length);
                    break;
                case 3:
                    bContentLen = HH_SystemUtil.Variable16ToArray(pContentGBK.length);
                    break;
            }

            pSaveInfo[index++] = bContentLen[0];
            pSaveInfo[index++] = bContentLen[1];
        }


        // 标题
        switch (tms.getMsgTaskFontType())
        {
            case 0:
                for (int i = 0; i < pTitleUnicode_UCS4.length; i++){
                    pSaveInfo[index++] = pTitleUnicode_UCS4[i];
                }
                break;
            case 1:
                for (int i = 0; i < pTitleAnsi.length; i++){
                    pSaveInfo[index++] = pTitleAnsi[i];
                }
                break;
            case 2:
                for (int i = 0; i < pTitleUnicode_UCS2.length; i++){
                    pSaveInfo[index++] = pTitleUnicode_UCS2[i];
                }
                break;
            case 3:
                for (int i = 0; i < pTitleGBK.length; i++){
                    pSaveInfo[index++] = pTitleGBK[i];
                }
                break;
        }


        // 内容
        switch (tms.getMsgTaskFontType())
        {
            case 0:
                for (int i = 0; i < pContentUnicode_UCS4.length; i++){
                    pSaveInfo[index++] = pContentUnicode_UCS4[i];
                }
                break;
            case 1:
                for (int i = 0; i < pContentAnsi.length; i++){
                    pSaveInfo[index++] = pContentAnsi[i];
                }
                break;
            case 2:
                for (int i = 0; i < pContentUnicode_UCS2.length; i++){
                    pSaveInfo[index++] = pContentUnicode_UCS2[i];
                }
                break;
            case 3:
                for (int i = 0; i < pContentGBK.length; i++){
                    pSaveInfo[index++] = pContentGBK[i];
                }
                break;
        }


        if (12 < nMaxLen)
        {
            // 计算文件累加和
            long lCheckSum = 0;
            for (int i = 12; i < index; i++)
                lCheckSum += ((byte)pSaveInfo[i] & 0xff);
            byte [] szCheckSum = HH_SystemUtil.Variable32ToArray(lCheckSum);
            pSaveInfo[4] = szCheckSum[0];
            pSaveInfo[5] = szCheckSum[1];
            pSaveInfo[6] = szCheckSum[2];
            pSaveInfo[7] = szCheckSum[3];

            // 计算文件大小
            byte [] szFileSize = HH_SystemUtil.Variable32ToArray(index - 12);
            pSaveInfo[8] = szFileSize[0];
            pSaveInfo[9] = szFileSize[1];
            pSaveInfo[10] = szFileSize[2];
            pSaveInfo[11] = szFileSize[3];
        }

        byte[] bResult = new byte[index];
        System.arraycopy(pSaveInfo, 0, bResult, 0, index);


        String sLog = "";
        for (int i = 0; i < bResult.length; i++)
            sLog += String.format("%02x, ", bResult[i]& 0xff);

        return bResult;
    }


    /**
     * 获取文件mime类型
     *
     * @param file
     * @return
     */
    public static String getMIMEType(File file) {
        String type = "*/*";
        String fName = file.getName();
        //获取后缀名前的分隔符"."在fName中的位置。
        int dotIndex = fName.lastIndexOf(".");
        if (dotIndex < 0) {
            return type;
        }
        /* 获取文件的后缀名 */
        String fileType = fName.substring(dotIndex, fName.length()).toLowerCase();
        if (fileType == null || "".equals(fileType)) {
            return type;
        }
        //在MIME和文件类型的匹配表中找到对应的MIME类型。
        for (int i = 0; i < MIME_MapTable.length; i++) {
            if (fileType.equals(MIME_MapTable[i][0]))
                type = MIME_MapTable[i][1];
        }
        return type;
    }

    public static HH_T_DIR_INFO GetPicPath(Context ctx, Uri uri) {
        HH_T_DIR_INFO diSrc;
        diSrc = HH_FileUtil.GetCurFileInfo(uri.getPath());
        if (diSrc.getExtN() != null && diSrc.getExtN().length() > 0) {
            return diSrc;
        } else {
            String sDstPath = HH_UriUtils.getFileAbsolutePath(ctx, uri);
            HH_T_DIR_INFO diDst = HH_FileUtil.GetCurFileInfo(sDstPath);
            return diDst;
        }
    }
    /**
     * 文件mime类型
     */
    private static final String[][] MIME_MapTable = {
            {".3gp", "video/3gpp"},
            {".apk", "application/vnd.android.package-archive"},
            {".asf", "video/x-ms-asf"},
            {".avi", "video/x-msvideo"},
            {".bin", "application/octet-stream"},
            {".bmp", "image/bmp"},
            {".c", "text/plain"},
            {".class", "application/octet-stream"},
            {".conf", "text/plain"},
            {".cpp", "text/plain"},
            {".doc", "application/msword"},
            {".exe", "application/octet-stream"},
            {".gif", "image/gif"},
            {".gtar", "application/x-gtar"},
            {".gz", "application/x-gzip"},
            {".h", "text/plain"},
            {".htm", "text/html"},
            {".html", "text/html"},
            {".jar", "application/java-archive"},
            {".java", "text/plain"},
            {".jpeg", "image/jpeg"},
            {".jpg", "image/jpeg"},
            {".js", "application/x-javascript"},
            {".log", "text/plain"},
            {".m3u", "audio/x-mpegurl"},
            {".m4a", "audio/mp4a-latm"},
            {".m4b", "audio/mp4a-latm"},
            {".m4p", "audio/mp4a-latm"},
            {".m4u", "video/vnd.mpegurl"},
            {".m4v", "video/x-m4v"},
            {".mov", "video/quicktime"},
            {".mp2", "audio/x-mpeg"},
            {".mp3", "audio/x-mpeg"},
            {".mp4", "video/mp4"},
            {".mpc", "application/vnd.mpohun.certificate"},
            {".mpe", "video/mpeg"},
            {".mpeg", "video/mpeg"},
            {".mpg", "video/mpeg"},
            {".mpg4", "video/mp4"},
            {".mpga", "audio/mpeg"},
            {".msg", "application/vnd.ms-outlook"},
            {".ogg", "audio/ogg"},
            {".pdf", "application/pdf"},
            {".png", "image/png"},
            {".pps", "application/vnd.ms-powerpoint"},
            {".ppt", "application/vnd.ms-powerpoint"},
            {".prop", "text/plain"},
            {".rar", "application/x-rar-compressed"},
            {".rc", "text/plain"},
            {".rmvb", "audio/x-pn-realaudio"},
            {".rtf", "application/rtf"},
            {".sh", "text/plain"},
            {".tar", "application/x-tar"},
            {".tgz", "application/x-compressed"},
            {".txt", "text/plain"},
            {".wav", "audio/x-wav"},
            {".wma", "audio/x-ms-wma"},
            {".wmv", "audio/x-ms-wmv"},
            {".wps", "application/vnd.ms-works"},
            //{".xml",    "text/xml"},
            {".xml", "text/plain"},
            {".z", "application/x-compress"},
            {".zip", "application/zip"},
            {"", "*/*"}
    };

    // 文件改名，
    public static void ReNameFile(String pathSrc, String pathDst) {
        if (pathSrc == null || pathDst == null || pathDst.length() <= 0 || !HH_FileUtil.IsExists(pathSrc))
            return;

        File fileDst = new File(pathDst);
        File fileSrc = new File(pathSrc);
        if (fileSrc != null){
            fileSrc.renameTo(fileDst);
        }

    }

    public static boolean CheckFile(String path, ArrayList<String> exts) {
        if (path == null)
            return false;
        if (exts == null || exts.size() <= 0)
            return true;

        HH_T_DIR_INFO td = HH_FileUtil.GetCurFileInfo(path);
        if (td == null || td.getExtN() == null || td.getExtN().length() <= 0)
            return false;

        for (int i = 0; i < exts.size(); i++){
            if (HH_CharUtil.Strcmp(td.getExtN(), exts.get(i), true)){
                return true;
            }
        }

        return false;
    }
}